﻿using System.Collections.Generic;
using System.Reflection;
using System;

namespace Layers.History
{
    public class ObjectStream : IStream
    {
        [System.NonSerialized]
        private FastReflectionLib.IConstructorInvoker _constructor;

        [System.NonSerialized]
        private IDictionary<string, IStream> _nodestreams;

        private ITypeColumns _container;


        public ObjectStream(ITypeColumns container, IDictionary<string, DataNode> map)
        {
            _container = container;
            _nodestreams = Factory.NewDictionary<string, IStream>();
            foreach (KeyValuePair<string, DataNode> kv in map)
            {
                _nodestreams.Add(kv.Key, kv.Value.GetStream());
            }

            ConstructorInfo ci = _container.Type.GetConstructor(new Type[0]);
            _constructor = FastReflectionLib.FastReflectionCaches.ConstructorInvokerCache.Get(ci);

        }

        #region IStorage Members

        protected virtual object NewObject()
        {
            return _constructor.Invoke(new object[0]);
        }


        public void Write(object src)
        {
            for (int i = 0; i < _container.Columns.Count; i++)
            {
                IColumn col = _container.Columns[i];
                object field = col.Accessor.GetValue(src);
                IStream stream = _nodestreams[col.Name];
                stream.Write(field);
            }
        }

        public object Read()
        {
            object dst = NewObject();
            for (int i = 0; i < _container.Columns.Count; i++)
            {
                IColumn col = _container.Columns[i];
                IStream stream = _nodestreams[col.Name];
                object field = stream.Read();
                col.Accessor.SetValue(dst, field);
            }
            return dst;
        }

        #endregion
    }
}